import {
	IContext,
	ICtrlService,
	IHttpResponse,
	IParam,
} from '@/core/interface';
import { deepCopy } from '@/core/utils';
import { ControlVOBase } from '../control-vo';

/**
 * 多实体部件服务基类
 *
 * @export
 * @class CtrlExServiceBase
 * @template T
 */
export class CtrlExServiceBase<T extends ControlVOBase[]>
	implements ICtrlService<T>
{
	/**
	 * 实体服务
	 *
	 * @type {*}
	 * @memberof CtrlExServiceBase
	 */
	protected appEntityService: any;

	/**
	 * 模型数据
	 *
	 * @type {IParam}
	 * @memberof CtrlExServiceBase
	 */
	public model!: IParam;

	/**
	 * 实体服务集合
	 *
	 * @private
	 * @type {Map<string, any>}
	 * @memberof CtrlExServiceBase
	 */
	public entityServiceMap: Map<string, any> = new Map();

	/**
	 * 实体codeName
	 *
	 * @private
	 * @type {Map<string, any>}
	 * @memberof CtrlExServiceBase
	 */
	public entityCodeName: string;

	/**
	 * 实体VO数组
	 *
	 * @private
	 * @type {Map<string, any>}
	 * @memberof CtrlExServiceBase
	 */
	public controlVOTypes: IParam[];

	/**
	 * Creates an instance of CtrlExServiceBase.
	 * @param {new (data: any) => T} controlVOType
	 * @memberof CtrlExServiceBase
	 */
	constructor(controlVOTypes: IParam[], entityCodeName: string, opts?: IParam) {
		this.entityCodeName = entityCodeName;
		this.controlVOTypes = controlVOTypes;
		this.initEntityService();
	}

	[key: string]: any;

	frontLogic(
		action: string,
		context?: IContext | undefined,
		params?: IParam | undefined
	): Promise<IHttpResponse<any>> {
		throw new Error('Method not implemented.');
	}

	/**
	 * 初始化实体服务
	 *
	 * @protected
	 * @return {*}  {Promise<void>}
	 * @memberof CtrlExServiceBase
	 */
	protected async initEntityService(): Promise<void> {
		if (this.appEntityService) {
			return;
		}
		try {
			this.appEntityService = await App.getDataService(this.entityCodeName);
		} catch (error) {
			console.error('获取实体服务异常', error);
		}
	}

	/**
	 * 新建部件界面数据对象
	 *
	 * @param {string} controlVoName
	 * @param {*} $DO
	 * @return {*}
	 * @memberof CtrlExServiceBase
	 */
	public newControlVO($DO: any, controlVoName: string) {
		const ControlVOType: any = this.controlVOTypes.find((controlVOType: any) =>
			Object.is(controlVOType.name, controlVoName)
		);
		if (ControlVOType && ControlVOType.controlVO) {
			return new ControlVOType.controlVO($DO);
		}
		return new ControlVOBase($DO);
	}

	/**
	 * 请求前处理函数
	 *
	 * @param {*} context
	 * @param {*} data
	 * @param {*} [opts={}]
	 * @return {*}
	 * @memberof CtrlExServiceBase
	 */
	public handleRequestData(context: any, data: any, opts: any = {}) {
		const tempContext: any = JSON.parse(JSON.stringify(context));
		if (tempContext && tempContext.srfsessionid) {
			tempContext.srfsessionkey = tempContext.srfsessionid;
			delete tempContext.srfsessionid;
		}
		const _data = deepCopy(data);
		if (data.viewParams && Object.keys(data.viewParams).length > 0) {
			Object.assign(_data, data.viewParams);
			delete _data.viewParams;
		}
		return { context: tempContext, data: _data };
	}

	/**
	 * 请求后处理函数
	 *
	 * @param {*} response
	 * @param {*} [opts={}]
	 * @return {*}
	 * @memberof CtrlExServiceBase
	 */
	public handleResponse(response: IHttpResponse, opts: any = {}) {
		return response;
	}

	/**
	 * 获取本地数据资源
	 *
	 * @return {*}  {Promise<IHttpResponse>}
	 * @memberof CtrlExServiceBase
	 */
	public async getLocalDataSource(): Promise<IHttpResponse> {
		return { data: {}, success: true };
	}
}
